package io.gitee.chearnee.fw.openapi.filter;

import cn.hutool.core.io.IoUtil;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.lang.Nullable;

import java.io.*;

/**
 * @Author: LiJiacheng 李嘉成 Jache
 * @Date: 2021/1/31 17:08
 * @Description:
 */
public class OpenApiHttpServletRequestWrapped extends HttpServletRequestWrapper {

  private final OpenApiHttpServletInputStream openApiHttpServletInputStream;
  private final byte[] data;
  @Nullable
  private BufferedReader reader;

  public OpenApiHttpServletRequestWrapped(HttpServletRequest request) throws IOException {
    super(request);
    // 读取输入流里的请求参数，并保存到bytes里
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    IoUtil.copy(request.getInputStream(), baos);
    data = baos.toByteArray();
    this.openApiHttpServletInputStream = new OpenApiHttpServletInputStream(
        new ByteArrayInputStream(data));
  }


  @Override
  public ServletInputStream getInputStream() throws IOException {
    return openApiHttpServletInputStream;
  }

  @Override
  public BufferedReader getReader() throws IOException {
    if (this.reader == null) {
      this.reader = new BufferedReader(
          new InputStreamReader(getInputStream(), getCharacterEncoding()));
    }
    return this.reader;
  }
//  /**
//   * 获取post参数，可以自己再转为相应格式
//   */
//  public Map<String, String[]> getRequestParams() throws IOException {
//    return super.getParameterMap();
//  }

  /**
   * 获取post参数，可以自己再转为相应格式
   *
   * @return
   * @throws IOException
   */
  public String getRequestParams() throws IOException {
    return new String(data, this.getCharacterEncoding());
  }

  private class OpenApiHttpServletInputStream extends ServletInputStream {

    private final InputStream stream;

    public OpenApiHttpServletInputStream(InputStream stream) {
      this.stream = stream;
    }

    @Override
    public int read() throws IOException {
      return stream.read();
    }

    @Override
    public boolean isFinished() {
      return false;
    }

    @Override
    public boolean isReady() {
      return false;
    }

    @Override
    public void setReadListener(ReadListener readListener) {

    }
  }
}
